#include <graphics.h>
#include <iostream>
#include <chrono>
#include "Scene/SceneManager.h"
#include "PlatformGame/PlatformJumpScene.h"
#include "PlatformGame/MenuScene.h"
#include "PlatformGame/GameOverScene.h"

using namespace GameEngine;

int main() {
    // Initialize graphics window
    initgraph(800, 600);
    setbkcolor(WHITE);
    cleardevice();
    
    // Enable double buffering to prevent screen flickering
    BeginBatchDraw();
      // Create scene manager
    SceneManager sceneManager;
    
    // Register all scenes
    sceneManager.RegisterScene<MenuScene>("Menu");
    sceneManager.RegisterScene<PlatformJumpScene>("PlatformJump");
    sceneManager.RegisterScene<GameOverScene>("GameOver");
    
    // Switch to menu scene first
    try {
        sceneManager.SwitchToScene("Menu");
    } catch (const std::exception& e) {
        std::cout << "Error: " << e.what() << std::endl;
        closegraph();
        return -1;
    }
    
    // Main game loop
    auto lastTime = std::chrono::high_resolution_clock::now();
    bool running = true;
    
    std::cout << "Game started, press ESC to exit" << std::endl;
    
    while (running) {
        // Calculate frame time
        auto currentTime = std::chrono::high_resolution_clock::now();
        float deltaTime = std::chrono::duration<float>(currentTime - lastTime).count();
        lastTime = currentTime;
        
        // Limit maximum frame time to avoid large jumps
        if (deltaTime > 0.05f) {
            deltaTime = 0.05f;
        }
        
        // Check exit condition
        if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
            running = false;
        }
          // Update scene
        sceneManager.UpdateCurrentScene(deltaTime);
        
        // Render scene
        sceneManager.RenderCurrentScene();
        
        // Flush the batch draw buffer to display the frame
        FlushBatchDraw();
        
        // Control frame rate (approximately 60FPS)
        Sleep(16);    }
    
    std::cout << "Game ended" << std::endl;
    
    // End batch drawing before closing
    EndBatchDraw();
    closegraph();
    return 0;
}
